package com.usefullc.crawler.task.impl;

import com.usefullc.common.enums.YesNoEnum;
import com.usefullc.crawler.domain.Active;
import com.usefullc.crawler.domain.ActiveInstance;
import com.usefullc.crawler.domain.Template;
import com.usefullc.crawler.enums.RequestResultErrorStatusEnum;
import com.usefullc.crawler.enums.RequestTypeEnum;
import com.usefullc.crawler.selenium.CrawlerWebDriver;
import com.usefullc.crawler.selenium.CrawlerWebDriverBuilder3;
import com.usefullc.crawler.service.*;
import com.usefullc.crawler.task.TaskMessage;
import com.usefullc.crawler.task.TaskMessageHandler;
import com.usefullc.crawler.task.TaskMessageQueue;
import com.usefullc.crawler.task.TaskRequestResult;
import com.usefullc.system.service.AbstractService;
import com.usefullc.system.service.DataConfigService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author: Sampson
 * @date: 2022-03-29 12:11
 */
@Service
public class DefaultTaskMessageHandler extends AbstractService implements TaskMessageHandler {

    @Autowired
    private TaskMessageQueue<Long> taskMessageQueue;

    @Autowired
    private SeleniumRequestService seleniumRequestService;

    @Autowired
    private HttpClientRequestService httpClientRequestService;

    @Autowired
    private DataConfigService dataConfigService;

    @Autowired
    private ActiveProcessService activeProcessService;

    @Autowired
    private ActiveInstanceService activeInstanceService;

    @Autowired
    private CrawlerWebDriverBuilder3 crawlerWebDriverBuilder;

    @Autowired
    private TemplateService templateService;

    private Map<String, ExecutorService> executorServiceMap = new HashMap<>();


    @Override
    public void run() {
        //创建线程池
//        ExecutorService executorService = Executors.newSingleThreadExecutor();
//        executorServiceMap.put(TaskSpeedEnum.SLOW.getCode(),executorService);
//        executorService = Executors.newFixedThreadPool(3);
//        executorServiceMap.put(TaskSpeedEnum.MIDDLE.getCode(),executorService);
//        executorService = Executors.newFixedThreadPool(5);
//        executorServiceMap.put(TaskSpeedEnum.FAST.getCode(),executorService);

        ExecutorService executorService = Executors.newFixedThreadPool(5);


//        AtomicBoolean atoBan = new AtomicBoolean(false);
        while(true){
            try{
//                while (atoBan.get()) {
//                    DataConfig dataConfig = dataConfigService.findByCode(CrawlerConstants.ACTIVE_TASK_INTERCEPT);
//                    if(!BooleanUtils.toBoolean(dataConfig.getValue())){
//                        atoBan.set(false);
//                        break;
//                    }
//                    Thread.sleep(2*1000);
//                }
                //获取selenium 任务
//                String reqType = RequestTypeEnum.SELENIUM.getValue();
                //这里的任务只拿主动执行的（比如selenium)
                TaskMessage<Long> taskMessage = taskMessageQueue.popTaskMessage(true);
                String reqType = taskMessage.getReqType();
                if(StringUtils.equalsIgnoreCase(reqType, RequestTypeEnum.SIMULATOR.getValue())){  //electron 不能采用同步
                    taskMessageQueue.addTaskMessage(taskMessage);
                    Thread.sleep(100);
                    continue;
                }

//                ExecutorService es = executorServiceMap.get(taskMessage.getSpeed());
                Thread.sleep(taskMessage.getSleepTime());
                executorService.execute(() -> {
                    long startTime = System.currentTimeMillis();
                    TaskRequestResult result = null;

                    if (StringUtils.equalsIgnoreCase(reqType, RequestTypeEnum.SIMULATOR.getValue())) {
                        result = seleniumRequestService.execute(taskMessage.getData());

                    }else if (StringUtils.equalsIgnoreCase(reqType, RequestTypeEnum.HTTP_API.getValue())) {
                        result = httpClientRequestService.execute(taskMessage.getData());

                    }
//                    else if(StringUtils.equalsIgnoreCase(reqType, RequestTypeEnum.HTML_UNIT.getValue())){
//                        //待实现 todo
//                        return;
//                    }
                    ActiveInstance activeInstance = result.getActiveInstance();
                    CrawlerWebDriver crawlerWebDriver = result.getCrawlerWebDriver();
                    //执行失败，添加到消息队列，重新执行
                    if(!result.isSuccess()){
                        if (result.getErrorStatus() == RequestResultErrorStatusEnum.BAN.getCode()) {
                            Template template = templateService.findById(activeInstance.getTemplateId());
                            if(template.getBanSwitchProxy() == YesNoEnum.YES.getCode()){
                                crawlerWebDriverBuilder.killAndBuildNew(crawlerWebDriver);
                            }else{
                                activeProcessService.setAtoIntercept(true);
                                activeProcessService.checkIntercept(activeInstance.getId());
                            }
//                            crawlerWebDriverBuilder.close(crawlerWebDriver);
//                            crawlerWebDriverBuilder.setAtoIntercept(true);


                        }else if (result.getErrorStatus() == RequestResultErrorStatusEnum.PROXY_ERROR.getCode()) {
//                            crawlerWebDriverBuilder.setAtoIntercept(true);  //暂时自动切换
                            crawlerWebDriverBuilder.killAndBuildNew(crawlerWebDriver);
                        }
                        taskMessageQueue.addTaskMessage(taskMessage);
                    }else{  //成功
                    }
                    crawlerWebDriverBuilder.close(crawlerWebDriver);
//                    if (!result.isSuccess() && result.getErrorStatus() == RequestResultErrorStatusEnum.PROXY_ERROR.getCode()) {
//                        crawlerWebDriverBuilder.killAndBuildNew(crawlerWebDriver);
//                    } else if(!result.isSuccess() && result.getErrorStatus() == RequestResultErrorStatusEnum.BAN.getCode()){
//                        activeProcessService.setAtoIntercept(true);
//                        activeProcessService.checkIntercept(activeInstance.getId());
//                        crawlerWebDriverBuilder.close(crawlerWebDriver);
//                    }else{
//                        crawlerWebDriverBuilder.close(crawlerWebDriver);
//                    }
                    long takeTime = System.currentTimeMillis() - startTime;
                    activeInstance.setTakeTime(takeTime);
                    try{
                        //任务结束，设置为0
                        activeInstance.setTaskStatus(YesNoEnum.NO.getCode());
                        //回写数据库
                        activeInstanceService.activeRequestUpdate(activeInstance);
                    }catch (Exception e){
                        logger.error("rewrite activeInstance failed",e);
                    }
                    logger.info("task execute finished,success={},errorStatus={},activeInstanceId={},url={}",result.isSuccess(),result.getErrorStatus(),activeInstance.getId(),activeInstance.getUrl());
                });

            }catch (Exception e){
                logger.error("selenium task run failed",e);

            }

        }
    }

//    @Override
//    public TaskMessage<Long> pull() {
//        TaskMessage<Long> taskMessage = taskMessageQueue.popTaskMessage(false);
//        return taskMessage;
//    }
}
